#include "SubSpecialLabelDlg.h"

#include <bondlib/BondSpecialLabel.h>
#include <core/FileSys.h>
#include <core/ImageMgr.h>
#include <core/StyleMgr.h>
#include <core/serialize/serializeImpl.h>
#include <include/rapidjson/document.h>
#include <include/rapidjson/prettywriter.h>
#include <include/rapidjson/rapidjson.h>
#include <include/rapidjson/stringbuffer.h>
#include <uam/UserAccountManager.h>
#include <uam/config/ConfigLocal.h>
#include <widgets/STabCtrl.h>
#include <widgets/table/STable.h>

#include <QApplication>
#include <QDesktopWidget>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QMouseEvent>
#include <QPushButton>
#include <QStylePainter>
#include <QVBoxLayout>
#include <fstream>
#include <iostream>

#include "../StringResource.h"

// tab1
SpecialLabelItemDelegate::SpecialLabelItemDelegate(QObject* p, int count)
    : QStyledItemDelegate(p) {
  m_vctChecks.resize(count);
}

void SpecialLabelItemDelegate::paint(QPainter* painter,
                                     const QStyleOptionViewItem& option,
                                     const QModelIndex& index) const {
  painter->fillRect(option.rect, StyleMgr::instance().color("TabBackNormal"));

  if (index.column() == 0) {
    painter->setRenderHint(QPainter::Antialiasing);

    m_vctChecks[index.row()].rect = option.rect;

    QString imageName;
    if (m_vctChecks[index.row()].check) {
      imageName = "widgets_check_selected";
    } else {
      imageName = "widgets_check";
    }

    SImage* img = ImgMgr::instance().image(imageName, WidgetStatus::kNormal);
    if (img) {
      int width = img->width();
      int height = img->height();
      int y = option.rect.y() + 5;

      painter->setRenderHint(QPainter::SmoothPixmapTransform);
      painter->drawImage(QRect(option.rect.x() + 3, y, width, height), *img);
    }
  } else if (index.column() == 1) {
    QRect rcClient(option.rect);
    rcClient.adjust(4, 0, 0, -4);
    QFont font = painter->font();
    font.setPixelSize(10);
    painter->setFont(font);
    painter->setPen(index.data(SpecialLabelColorRole).value<QColor>());
    painter->drawText(rcClient.adjusted(2, 0, 0, 0),
                      Qt::AlignLeft | Qt::AlignVCenter,
                      index.data(SpecialLabelTextRole).value<QString>());
    font.setPixelSize(12);
    painter->setFont(font);
    QRect txtRect = painter->fontMetrics().boundingRect(
        index.data(SpecialLabelTextRole).value<QString>());
    QRect rcRect(rcClient);
    rcRect.setRight(rcRect.left() + txtRect.width());
    painter->drawRoundedRect(rcRect.adjusted(0, 4, 0, -4), 2, 2);
    rcClient.setLeft(rcClient.left() + txtRect.width() + 4);

    QString id = index.data(SpecialLabelIdRole).value<QString>();
    int count = index.data(SpecialLabelCommentCountRole).value<int>();
    for (int i = 0; i < count; ++i) {
      QString str =
          index.data(SpecialLabelCommentBeginRole + i).value<QString>();

      QColor color =
          index.data(SpecialLabelCommentColorBeginRole + i).value<QColor>();
      if (m_vctChecks[index.row()].check && i == 0 && !str.isEmpty() &&
          str[0] != L'（') {
        color = StyleMgr::instance().color("Highlight");
      }
      if (isLabelFlag(str, id)) {
        font.setPixelSize(10);
        painter->setFont(font);
        painter->setPen(color);
        painter->drawText(rcClient.adjusted(2, 0, 0, 0),
                          Qt::AlignLeft | Qt::AlignVCenter,
                          index.data(SpecialLabelTextRole).value<QString>());
        font.setPixelSize(12);
        painter->setFont(font);
        txtRect = painter->fontMetrics().boundingRect(
            index.data(SpecialLabelTextRole).value<QString>());

        rcRect = rcClient;
        rcRect.setRight(rcRect.left() + txtRect.width());
        painter->drawRoundedRect(rcRect.adjusted(0, 4, 0, -4), 2, 2);
      } else {
        font.setPixelSize(12);
        painter->setFont(font);
        painter->setPen(color);
        painter->drawText(rcClient, Qt::AlignLeft | Qt::AlignVCenter, str);
        txtRect = painter->fontMetrics().boundingRect(
            index.data(SpecialLabelCommentBeginRole + i).value<QString>());
      }

      rcClient.setLeft(rcClient.left() + txtRect.width() + 4);
    }
  }

  QPen pen;
  pen.setColor(StyleMgr::instance().color("BackNormal"));
  pen.setWidth(5);
  painter->setPen(pen);
  painter->drawLine(option.rect.left(), option.rect.bottom(),
                    option.rect.right(), option.rect.bottom());

  if (0 == index.column()) {
    painter->drawLine(option.rect.right(), option.rect.top(),
                      option.rect.right(), option.rect.bottom());
  }
}

void SpecialLabelItemDelegate::hitCheck(int row) {
  if (row < 0 || row >= (int)m_vctChecks.size()) {
    return;
  }

  m_vctChecks[row].check = !m_vctChecks[row].check;
}

void SpecialLabelItemDelegate::check(int row, bool check) {
  m_vctChecks[row].check = check;
}

void SpecialLabelItemDelegate::getCheck(std::vector<int>& vctCheck) {
  vctCheck.clear();
  for (int i = 0; i < (int)m_vctChecks.size(); ++i) {
    if (m_vctChecks[i].check) {
      vctCheck.push_back(i);
    }
  }
}

void SpecialLabelItemDelegate::clearCheck() {
  for (int i = 0; i < (int)m_vctChecks.size(); ++i) {
    m_vctChecks[i].check = false;
  }
}

bool SpecialLabelItemDelegate::isLabelFlag(const QString& str,
                                           const QString& id) const {
  QString strID;
  strID = QString(tr("${%1}")).arg(id);
  return str == strID;
}

SpecialLabelConfig* SpecialLabelConfig::GetInstance() {
  static SpecialLabelConfig conf;
  return &conf;
}

SpecialLabelConfig::SpecialLabelConfig() : m_isSaved(false) {
  QString strAppPath = FileSys::instance()->writeableAppCfgDir();
  strAppPath.append("/");
  strAppPath += SSUserAccountManager::instance().GetUserInfo().m_UserAccount;
  strAppPath.append("/");

  FileSys::instance()->makePathExist(strAppPath);

  m_configPathName = strAppPath + "SpecialLabelConfig.json";
  Load();
}

bool SpecialLabelConfig::IsSaved() const { return m_isSaved; }

bool SpecialLabelConfig::CanShow(const string& id) const {
  auto iter = std::find(m_vecIDs.begin(), m_vecIDs.end(), id);
  return (iter != m_vecIDs.end());
}

void SpecialLabelConfig::Save(const vector<string>& ids) {
  m_vecIDs = ids;
  m_isSaved = true;
  Save();
}

void SpecialLabelConfig::Save() {
  rapidjson::StringBuffer buf;
  rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
  writer.StartObject();
  writer.Key("saved");
  writer.Bool(m_isSaved);
  writer.Key("id");
  writer.StartArray();
  for (size_t i = 0; i < m_vecIDs.size(); i++) {
    const string& id = m_vecIDs[i];
    writer.String(id.c_str());
  }
  writer.EndArray();
  writer.EndObject();
  const char* json_content = buf.GetString();

  try {
    std::ofstream out(m_configPathName.toStdString());
    out << json_content << std::endl;
    out.close();
  } catch (...) {
  }
}

bool SpecialLabelConfig::Load() {
  std::ifstream in(m_configPathName.toStdString());
  std::string json_content((std::istreambuf_iterator<char>(in)),
                           std::istreambuf_iterator<char>());
  in.close();

  rapidjson::Document doc;
  if (json_content.empty() || doc.Parse(json_content.c_str()).HasParseError()) {
    return false;
  }

  if (doc.HasMember("saved") && doc["saved"].IsBool()) {
    m_isSaved = doc["saved"].GetBool();
  }

  if (doc.HasMember("id") && doc["id"].IsArray()) {
    for (rapidjson::SizeType i = 0; i < doc["id"].Size(); i++) {
      const rapidjson::Value& val = doc["id"][i];
      if (!val.IsString() || val.IsNull()) {
        continue;
      }
      string id = val.GetString();
      m_vecIDs.emplace_back(id);
    }
  }
  return true;
}

// tab2
#define ParserArrayMap(KEY, VALUE)                                          \
  if (input[#KEY].isArray()) {                                              \
    Json::Value& pages = input[#KEY];                                       \
    for (Json::ValueIterator it = pages.begin(); it != pages.end(); ++it) { \
      VALUE unit;                                                           \
      unit.Parser(*it);                                                     \
      KEY[unit.m_type] = unit;                                              \
    }                                                                       \
  }

Json::Value Model_CopySequence::Wrapper() const {
  WrapperBegin();
  WrapperMap(m_tabs);
  WrapperEnd();
}

void Model_CopySequence::Parser(Json::Value& input) {
  ParserArrayMap(m_tabs, Model_CopySequenceTab);
}

Json::Value Model_CopySequence::Model_CopySequenceTab::Wrapper() const {
  WrapperBegin();
  WrapperValue(m_type);
  WrapperArrayInt(m_selects);
  WrapperEnd();
}

void Model_CopySequence::Model_CopySequenceTab::Parser(Json::Value& input) {
  ParserInt(m_type);
  ParserArrayInt(m_selects);
}

bool Model_CopySequence::Model_CopySequenceTab::GetCardName(QString& result,
                                                            int index) {
  result = NewStringTable::SequenceSaveName(index, true);

  if (result.isEmpty()) return false;
  return true;
}

int Model_CopySequence::Model_CopySequenceTab::GetAllCardsCnt() {
  return col::colMax;
}

void Model_CopySequence::Model_CopySequenceTab::Initialize() {
  if (m_selects.empty()) {
    switch (m_type) {
      case Model_CopySequence::tabTreasury: {
        m_selects = {colMty,       colTicker, colName, colBidOfr,
                     colVolBidOfr, colBroker, colCdc,  colTime};
        break;
      }
      case Model_CopySequence::tabLocal: {
        m_selects = {colMty,    colTicker,    colName,   colMunicipalBondType,
                     colBidOfr, colVolBidOfr, colRating, colBroker,
                     colCdc,    colTime};
        break;
      }
      case Model_CopySequence::tabCredit: {
        m_selects = {colMty,    colTicker,    colName,   colIssueMethod,
                     colBidOfr, colVolBidOfr, colRating, colBroker,
                     colCdc,    colTime};
        break;
      }
      case Model_CopySequence::tabNCD: {
        m_selects = {colMty,    colTicker, colName, colBidOfr, colVolBidOfr,
                     colRating, colBroker, colCdc,  colTime};
        break;
      }

      default:
        break;
    }
  }
}

void Model_CopySequence::Model_CopySequenceTab::Reset() {
  m_selects.clear();
  Initialize();
}

//////////////////////////////////////////////////////////////////////////

SubSpecialLabelDlg::SubSpecialLabelDlg(QWidget* p /*= nullptr*/)
    : SPopupWindow(p) {
  setTitle(tr("设置"));
  setFixedSize(550, 438);
  setAcceptDrops(false);

  QDesktopWidget* desk = QApplication::desktop();
  int numScreens = desk->screenCount();
  for (int i = 0; i < numScreens; ++i) {
    QRect screenGeometry = desk->screenGeometry(i);
    if (screenGeometry.contains(QCursor::pos())) {
      this->move(screenGeometry.x() + (screenGeometry.width() - width()) / 2,
                 screenGeometry.y() + (screenGeometry.height() - height()) / 2);
      break;
    }
  }

  QVBoxLayout* vLayout = new QVBoxLayout(this);
  vLayout->setContentsMargins(112, 4, 0, 0);

  // tab1
  m_spacer =
      new QSpacerItem(20, 28, QSizePolicy::Expanding, QSizePolicy::Fixed);
  vLayout->addSpacerItem(m_spacer);
  m_tableView = new QTableView(this);
  m_model = new QStandardItemModel(0, 2, this);
  m_tableView->setModel(m_model);
  m_tableView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  m_tableView->setFrameShape(QFrame::NoFrame);
  m_tableView->setShowGrid(false);
  m_tableView->setAutoScroll(true);
  m_tableView->setFocusPolicy(Qt::NoFocus);
  m_tableView->horizontalHeader()->setVisible(false);
  m_tableView->verticalHeader()->setVisible(false);
  m_tableView->setColumnWidth(0, 24);
  m_tableView->setColumnWidth(1, 386);
  m_tableView->setSelectionMode(QAbstractItemView::NoSelection);
  m_tableView->setEditTriggers(QAbstractItemView::SelectedClicked);
  m_tableView->setStyleSheet(
      QString("QTableView {background-color: #%1; color: #%2; border: none;}")
          .arg(StyleMgr::instance().color("ElementBackground").rgb(), 0, 16)
          .arg(StyleMgr::instance().color("TextNormal").rgb(), 0, 16));

  m_tableView->setFixedHeight(330);

  std::vector<SpecialLabel> labels = SpecialLabelMgr::instance().getAll();
  for (size_t i = 0; i < labels.size(); i++) {
    const SpecialLabel& label = labels[i];

    QColor color;
    hexStrToInt(label.color().c_str(), label.color().length(), color);
    tagLineValue line;
    line.id = QString::fromLocal8Bit(label.id().c_str());
    line.label = QString::fromLocal8Bit(label.label().c_str());
    line.color = color;
    line.check = label.IsDefaultCanShow();
    splitComments(QString::fromLocal8Bit(label.comment().c_str()),
                  line.comments);
    m_datas.push_back(line);
  }

  m_delegate = new SpecialLabelItemDelegate(this, (int)m_datas.size());
  m_tableView->setItemDelegate(m_delegate);
  m_model->setRowCount((int)m_datas.size());

  for (int row = 0; row < (int)m_datas.size(); ++row) {
    QStandardItem* item0 = m_model->item(row, 0);
    if (item0 == nullptr) {
      item0 = new QStandardItem();
    }

    item0->setData(true, Qt::EditRole);

    if (SpecialLabelConfig::GetInstance()->IsSaved()) {
      bool checked = SpecialLabelConfig::GetInstance()->CanShow(
          m_datas[row].id.toStdString());
      m_delegate->check(row, checked);
    } else {
      if (m_datas[row].check) {
        m_delegate->check(row, true);
      }
    }

    QStandardItem* item1 = m_model->item(row, 1);
    if (item1 == nullptr) {
      item1 = new QStandardItem();
    }

    item1->setData(m_datas[row].color, SpecialLabelColorRole);
    item1->setData(m_datas[row].label, SpecialLabelTextRole);
    item1->setData(m_datas[row].id, SpecialLabelIdRole);

    int count = m_datas[row].comments.size();
    item1->setData(count, SpecialLabelCommentCountRole);
    for (int i = 0; i < count; ++i) {
      item1->setData(m_datas[row].comments[i].color,
                     SpecialLabelCommentColorBeginRole + i);
      item1->setData(m_datas[row].comments[i].str,
                     SpecialLabelCommentBeginRole + i);
    }

    m_tableView->setRowHeight(row, 28);
    m_model->setItem(row, 0, item0);
    m_model->setItem(row, 1, item1);
  }

  vLayout->addWidget(m_tableView);
  connect(m_tableView, &QTableView::clicked, this,
          &SubSpecialLabelDlg::onSpecialLabelCheckClick);

  // tab2
  char keyConfig[] = "DataProtocol_Local_CopySequence";
  m_reqImpl.UnSerialize(ConfigLocal::Get()->GetConfig(keyConfig));
  for (int index = Model_CopySequence::tabTreasury;
       index < Model_CopySequence::tabMax; ++index) {
    m_reqImpl.m_tabs[index].m_type = index;
    m_reqImpl.m_tabs[index].Initialize();
  }

  loadQuoteCopy();

  m_QuoteCopyTab = new STabCtrl(this);
  m_QuoteCopyTab->setFixedSize(418, 24);
  QString tips = tr("支持国债、政金债和央票的自定义复制");
  const QStringList nameList = {tr("国债/政金债"), tr("地方债政府"),
                                tr("信用债"), tr("NCD")};
  for (int i = 0; i < nameList.length(); ++i) {
    m_QuoteCopyTab->addTab(nameList[i]);
    m_QuoteCopyTab->showSelBorder(i, true, "TabSelBorder");

    if (0 == i) {
      m_QuoteCopyTab->setTabInfo(i, "widgets_circle_info", tips);
    }
  }
  m_QuoteCopyTab->selectTab(0);
  m_QuoteCopyTab->hide();
  vLayout->addWidget(m_QuoteCopyTab);
  connect(m_QuoteCopyTab, &STabCtrl::tabSelected, [=]() {
    m_nQuoteCopyTabSel = m_QuoteCopyTab->getSelTab();
    onQuoteCopyTabSel();
  });

  m_BondCopyPanel = new QWidget(this);
  m_BondCopyPanel->setSizePolicy(QSizePolicy::Expanding,
                                 QSizePolicy::Expanding);
  m_BondCopyPanel->hide();
  vLayout->addWidget(m_BondCopyPanel);
  m_contentLayout->addLayout(vLayout);

  QHBoxLayout* hLayout = new QHBoxLayout(m_BondCopyPanel);
  hLayout->setContentsMargins(2, 30, 8, 30);

  QString strStyleSheet(
      tr("QListView {background-color: #%5;color: #%2;border: 1px solid "
         "#%5;} "
         "QListView::item {background-color: #%1;padding: 4px;height: "
         "24px;color: #%2;border: 2px solid #%5;}"
         "QListView::item:selected {background-color: #%1;color: #%2;}"
         "QListView::item:hover {background-color: #%3;color: #%2;}"
         "QListView::indicator {width: 16px;height: 16px;}"
         "QListView::indicator:checked {background-color: #%4;"
         "image: url(:/qb/check_selected_normal.png)}"
         "QListView::indicator:unchecked {background-color: #%4;border: 1px "
         "solid #%6;}")
          .arg(StyleMgr::instance().color("TabBackNormal").rgb(), 0, 16)
          .arg(StyleMgr::instance().color("TextNormal").rgb(), 0, 16)
          .arg(StyleMgr::instance().color("MenuTitleBack").rgb(), 0, 16)
          .arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16)
          .arg(StyleMgr::instance().color("ElementBackground").rgb(), 0, 16)
          .arg(StyleMgr::instance().color("TipsBorder").rgb(), 0, 16));

  m_listUnSel = new QListView(m_BondCopyPanel);
  m_listUnSel->setFocusPolicy(Qt::NoFocus);
  m_listUnSel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
  m_listUnSel->setStyleSheet(strStyleSheet);
  m_listUnSel->setFixedSize(180, 300);

  m_listSel = new SDragListWidget(m_BondCopyPanel);
  m_listSel->setFocusPolicy(Qt::NoFocus);
  m_listSel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
  m_listSel->setStyleSheet(strStyleSheet);
  m_listSel->setFixedSize(180, 300);

  hLayout->addWidget(m_listUnSel);
  hLayout->addSpacerItem(
      new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding));
  hLayout->addWidget(m_listSel);

  connect(m_listUnSel, &QListView::clicked,
          [this](const QModelIndex& index) { onQuoteCopyUnSelCheck(); });

  connect(m_listSel, &QListView::clicked,
          [this](const QModelIndex& index) { onQuoteCopySelCheck(); });

  QColor clrBk = StyleMgr::instance().color("Hover");
  m_btnSel = new SImageButton(this, "guiframe_triangle_right");
  m_btnSel->setColor(clrBk, clrBk, clrBk, clrBk);
  m_btnSel->setDisabled(true);
  m_btnSel->hide();
  connect(m_btnSel, &SImageButton::clicked, this, [this](int) {});

  m_btnUnSel = new SImageButton(this, "guiframe_triangle_left");
  m_btnUnSel->setColor(clrBk, clrBk, clrBk, clrBk);
  m_btnUnSel->setDisabled(true);
  m_btnUnSel->hide();
  connect(m_btnUnSel, &SImageButton::clicked, this, [this](int) {});

  m_btnLayout->setContentsMargins(112, 36, 0, 0);
  addBtn(QMessageBox::Ok, tr("确定"));
  addBtn(QMessageBox::Cancel, tr("取消"));
  addBtn(QMessageBox::Apply, tr("清空选项"));

  connect(m_btnOK, &QPushButton::clicked, this, &SubSpecialLabelDlg::onBtnOk);
  connect(m_btnCancel, &QPushButton::clicked, this,
          &SubSpecialLabelDlg::onBtnCancel);
  connect(m_btnApply, &QPushButton::clicked, this,
          &SubSpecialLabelDlg::onBtnApply);

  onQuoteCopyTabSel();
}

void SubSpecialLabelDlg::paintEvent(QPaintEvent* event) {
  SPopupWindow::paintEvent(event);
  QStylePainter painter(this);

  QRect rcClient = rect();
  rcClient.adjust(0, m_nTitleHeight, 0, 0);
  painter.setPen(StyleMgr::instance().color("SeperateLine"));
  painter.drawLine(QPoint(rcClient.left() + 110, rcClient.top() + 4),
                   QPoint(rcClient.left() + 110, rcClient.bottom() - 4));

  m_rcSpecialLabel = rcClient;
  m_rcSpecialLabel.adjust(6, 6, 0, 0);
  m_rcSpecialLabel.setRight(m_rcSpecialLabel.left() + 94);
  m_rcSpecialLabel.setBottom(m_rcSpecialLabel.top() + 40);

  m_rcQuoteCopy = m_rcSpecialLabel;
  m_rcQuoteCopy.setTop(m_rcQuoteCopy.bottom());
  m_rcQuoteCopy.setBottom(m_rcQuoteCopy.top() + 40);

  if (0 == m_nLeftPanelSel) {
    m_btnApply->setText(tr("清空选项"));
    painter.fillRect(m_rcSpecialLabel,
                     StyleMgr::instance().color("TabBackNormal"));
    painter.fillRect(m_rcQuoteCopy,
                     StyleMgr::instance().color("ElementBackground"));

    painter.setPen(StyleMgr::instance().color("TabSelBorder"));
    painter.drawText(m_rcSpecialLabel.adjusted(8, 0, 0, 0), tr("特殊标签"),
                     QTextOption(Qt::AlignLeft | Qt::AlignVCenter));

    painter.setPen(StyleMgr::instance().color("TextNormal"));
    painter.drawText(m_rcQuoteCopy.adjusted(8, 0, 0, 0), tr("报价价格复制"),
                     QTextOption(Qt::AlignLeft | Qt::AlignVCenter));

    QRect rcText(rcClient);
    rcText.adjust(120, 10, 0, 0);
    painter.drawText(rcText, tr("请勾选需要显示的标签："),
                     QTextOption(Qt::AlignLeft | Qt::AlignTop));
  } else {
    m_btnApply->setText(tr("恢复默认"));
    painter.fillRect(m_rcSpecialLabel,
                     StyleMgr::instance().color("ElementBackground"));
    painter.fillRect(m_rcQuoteCopy,
                     StyleMgr::instance().color("TabBackNormal"));

    painter.setPen(StyleMgr::instance().color("TextNormal"));
    painter.drawText(m_rcSpecialLabel.adjusted(8, 0, 0, 0), tr("特殊标签"),
                     QTextOption(Qt::AlignLeft | Qt::AlignVCenter));

    painter.setPen(StyleMgr::instance().color("TabSelBorder"));
    painter.drawText(m_rcQuoteCopy.adjusted(8, 0, 0, 0), tr("报价价格复制"),
                     QTextOption(Qt::AlignLeft | Qt::AlignVCenter));

    QRect rcPanel(rcClient);
    rcPanel.adjust(120, 36, 0, -62);
    rcPanel.setWidth(184);
    painter.setPen(StyleMgr::instance().color("TipsBorder"));
    painter.drawRoundedRect(rcPanel, 2, 2);

    QRect rcText(rcPanel);
    rcPanel.adjust(232, 0, 232, 0);
    painter.drawRoundedRect(rcPanel, 2, 2);

    painter.setPen(StyleMgr::instance().color("TextNormal"));
    painter.drawText(rcText.adjusted(4, 6, 0, 0), tr("未选字段"),
                     QTextOption(Qt::AlignLeft | Qt::AlignTop));

    rcText.adjust(234, 0, 234, 0);
    painter.drawText(rcText.adjusted(4, 6, 0, 0), tr("已选字段"),
                     QTextOption(Qt::AlignLeft | Qt::AlignTop));

    rcText.adjust(84, 0, 0, 0);
    painter.drawText(rcText.adjusted(0, 6, 0, 0), tr("拖拽调整复制顺序"),
                     QTextOption(Qt::AlignLeft | Qt::AlignTop));
  }
}

void SubSpecialLabelDlg::resizeEvent(QResizeEvent* event) {
  SPopupWindow::resizeEvent(event);

  QRect rcPanel(rect());
  rcPanel.adjust(120, 36, 0, -62);
  rcPanel.setWidth(184);

  QRect rcBtnSel(rcPanel);
  rcBtnSel.setLeft(rcBtnSel.right() + 14);
  rcBtnSel.setRight(rcBtnSel.left() + 24);
  rcBtnSel.setTop(rcPanel.top() + rcPanel.height() / 2 - 26);
  rcBtnSel.setBottom(rcBtnSel.top() + 24);

  QRect rcBtnUnSel(rcBtnSel);
  rcBtnUnSel.adjust(0, 30, 0, 30);

  if (m_btnSel != nullptr) {
    m_btnSel->setGeometry(rcBtnSel);
  }
  if (m_btnUnSel != nullptr) {
    m_btnUnSel->setGeometry(rcBtnUnSel);
  }
}

void SubSpecialLabelDlg::mousePressEvent(QMouseEvent* event) {
  if (m_rcSpecialLabel.contains(event->pos())) {
    m_QuoteCopyTab->hide();
    m_BondCopyPanel->hide();
    m_btnSel->hide();
    m_btnUnSel->hide();
    m_spacer->changeSize(20, 28, QSizePolicy::Expanding, QSizePolicy::Fixed);
    m_tableView->show();
    m_nLeftPanelSel = 0;
    update();
    return;
  } else if (m_rcQuoteCopy.contains(event->pos())) {
    m_tableView->hide();
    m_spacer->changeSize(20, 0, QSizePolicy::Expanding, QSizePolicy::Fixed);
    m_QuoteCopyTab->show();
    m_BondCopyPanel->show();
    m_btnSel->show();
    m_btnUnSel->show();
    m_nLeftPanelSel = 1;
    update();
    return;
  }

  SPopupWindow::mousePressEvent(event);
}

void SubSpecialLabelDlg::onSpecialLabelCheckClick(const QModelIndex& index) {
  if (index.column() == 0) {
    m_delegate->hitCheck(index.row());
    m_tableView->update();
  }
}

void SubSpecialLabelDlg::onBtnOk() {
  if (0 == m_nLeftPanelSel) {
    std::vector<int> vctCheck;
    m_delegate->getCheck(vctCheck);

    std::vector<std::string> ids;
    for (int i = 0; i < (int)vctCheck.size(); ++i) {
      ids.emplace_back(m_datas[vctCheck[i]].id.toStdString());
    }
    SpecialLabelConfig::GetInstance()->Save(ids);
  }
  close();
}

void SubSpecialLabelDlg::onBtnCancel() { close(); }

void SubSpecialLabelDlg::onBtnApply() {
  if (0 == m_nLeftPanelSel) {
    m_delegate->clearCheck();
  } else {
  }
}

void SubSpecialLabelDlg::onQuoteCopyTabSel() {

  m_listUnSel->setModel(m_modelUnSel[m_nQuoteCopyTabSel]);
  m_listSel->setModel(m_modelSel[m_nQuoteCopyTabSel]);
  onQuoteCopyUnSelCheck();
  onQuoteCopySelCheck();
}

void SubSpecialLabelDlg::onQuoteCopyUnSelCheck() {
  int i = 0;
  for (i = 0; i < m_modelUnSel[m_nQuoteCopyTabSel]->rowCount(); ++i) {
    QModelIndex index = m_modelUnSel[m_nQuoteCopyTabSel]->index(i, 0);
    Qt::CheckState state =
        index.data(Qt::CheckStateRole).value<Qt::CheckState>();
    if (state == Qt::Checked) {
      m_btnSel->setDisabled(false);
      break;
    }
  }

  if (i >= m_modelUnSel[m_nQuoteCopyTabSel]->rowCount()) {
    m_btnSel->setDisabled(true);
  }
}

void SubSpecialLabelDlg::onQuoteCopySelCheck() {
  int i = 0;
  for (i = 0; i < m_modelSel[m_nQuoteCopyTabSel]->rowCount(); ++i) {
    QModelIndex index = m_modelSel[m_nQuoteCopyTabSel]->index(i, 0);
    Qt::CheckState state =
        index.data(Qt::CheckStateRole).value<Qt::CheckState>();
    if (state == Qt::Checked) {
      m_btnUnSel->setDisabled(false);
      break;
    }
  }

  if (i >= m_modelSel[m_nQuoteCopyTabSel]->rowCount()) {
    m_btnUnSel->setDisabled(true);
  }
}

void SubSpecialLabelDlg::loadQuoteCopy() {
  for (int i = Model_CopySequence::tabTreasury; i < Model_CopySequence::tabMax;
       ++i) {
    std::set<int> setYes;
    for (auto it : m_reqImpl.m_tabs[i].m_selects) {
      setYes.insert(it);
    }

    m_quoteCopy[i].vctUnSel.clear();
    for (int index = 0; index < m_reqImpl.m_tabs[i].GetAllCardsCnt(); ++index) {
      if (setYes.find(index) != setYes.end()) continue;
      m_quoteCopy[i].vctUnSel.push_back(index);
    }

    m_quoteCopy[i].vctSel.clear();
    for (auto it : m_reqImpl.m_tabs[i].m_selects) {
      QString strCardName;
      if (!m_reqImpl.m_tabs[i].GetCardName(strCardName, it)) continue;
      m_quoteCopy[i].vctSel.push_back(it);
    }

    m_modelUnSel[i] = new QStandardItemModel(m_listUnSel);
    for (int j = 0; j < (int)m_quoteCopy[i].vctUnSel.size();
         ++j) {
      QString strCardName;
      if (!m_reqImpl.m_tabs[i].GetCardName(
              strCardName, m_quoteCopy[i].vctUnSel[j]))
        continue;

      QStandardItem* item = new QStandardItem(strCardName);
      item->setCheckable(true);
      item->setCheckState(Qt::Unchecked);
      m_modelUnSel[i]->appendRow(item);
    }

    m_modelSel[i] = new SDragListItemModel(this);
    for (int j = 0; j < (int)m_quoteCopy[i].vctSel.size();
         ++j) {
      QString strCardName;
      if (!m_reqImpl.m_tabs[i].GetCardName(
              strCardName, m_quoteCopy[i].vctSel[j]))
        continue;

      QStandardItem* item = new QStandardItem(strCardName);
      item->setCheckable(true);
      item->setCheckState(Qt::Unchecked);
      m_modelSel[i]->appendRow(item);
    }
  }
}

bool SubSpecialLabelDlg::splitComments(const QString& str,
                                       vector<tagField>& vecField) {
  if (str.isEmpty()) return true;
  vecField.clear();
  QString tmp;
  tagField field;
  for (int i = 0; i < str.length(); i++) {
    QChar ch = str.at(i);
    if (ch == '<') {
      if (!tmp.isEmpty()) {
        field.str = tmp;
        vecField.push_back(field);
        tmp.clear();
      }
    } else if (ch != '<' && ch != '>') {
      tmp += ch;
    } else if (ch == '>') {
      if (!tmp.isEmpty()) {
        QColor clr;
        hexStrToInt(tmp.toStdString().c_str(), tmp.length(), clr);
        field.color = clr;
        tmp.clear();
      }
    }
  }
  if (!tmp.isEmpty()) {
    field.str = tmp;
    vecField.push_back(field);
  }
  return true;
}

bool SubSpecialLabelDlg::hexStrToInt(const char* str, int len, QColor& value) {
  if (str == NULL || len != 10) return false;
  if (strncmp(str, "0x", 2) != 0) return false;
  int nums[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  unsigned int temp = 0;
  for (int i = 7; i >= 0; i--) {
    char c = str[2 + i];
    if (c >= 'a' && c <= 'f')
      nums[i] = c - 'a' + 10;
    else if (c >= 'A' && c <= 'F')
      nums[i] = c - 'A' + 10;
    else if (c >= '0' && c <= '9')
      nums[i] = c - '0';
    else
      return false;
    if (i < 7) {
      temp += nums[i] * (16 << ((6 - i) * 4));
    } else {
      temp += nums[i];
    }
  }
  value = temp;

  int red = temp & 255;
  int green = (temp >> 8) & 255;
  int blue = (temp >> 16) & 255;
  value = QColor(red, green, blue);

  return true;
}